﻿
// 2020/8/26: 首个记录（根据env-sample-v2.h 2020/5/15版本修改）
// 2020/11/3: 新增气压、相对湿度、能见度、风向、风速、PM10、道路状况、车道交通状况、灾害情况等字段。道路交通状况更名
// 2020/11/12: 支持Spadas7
// 2020/11/26: 实现fromGeneralSample
// 2022/11/2: 支持Spadas8.4
// 2023/8/17: 新增瞬时雨量字段
// 2023/10/10: 补充部分英文注释
// 2023/10/24: 新增字段（累计雨量、精确风向、总辐射强度、紫外线辐射强度、臭氧浓度、一氧化碳浓度、二氧化硫浓度、二氧化氮浓度）
// 2024/7/3: 基于新样本框架。枚举改为使用enum class
// 2025/3/25: 实现interpolate

#ifndef ENV_SAMPLE_V3_H
#define ENV_SAMPLE_V3_H

#include "spadas.h"

namespace env_sample_v3
{
	using namespace spadas;

	enum class WeatherType
	{
		Unknown = 0, // 未知
		Sunny = 1, // 晴
		Cloudy = 2, // 阴
		Rainy = 3, // 雨
		Snowy = 4, // 雪
		Foggy = 5, // 雾
		Sand = 6, // 沙尘
	};

	enum class RoadType
	{
		Unknown = 0, // 未知
		Highway = 1, // Without traffic light / 高速路，无红绿灯
		CityExpress = 2, // Without traffic light / 城市快速路，无红绿灯
		CityMain = 3, // With traffic light / 城市主干道，有红绿灯
		GeneralRoad = 4, // With traffic light / 一般道路，有红绿灯
		CountryRoad = 5, // Without traffic light / 乡村道路，无红绿灯
	};

	enum class SpotType
	{
		Unknown = 0, // 未知
		TollGate = 1, // 收费站
		ServiceArea = 2, // 服务区
		Tunnel = 3, // 隧道
		Accident = 4, // 事故
		Crossing = 5, // Intersection / 路口
		Roundabout = 7, // 环岛
		HighwayEntrance = 8, // 高速入口
		HighwayExit = 9, // 高速出口
		Bridge = 10, // 桥
		ExpressEntrance = 11, // 快速路入口
		ExpressExit = 12, // 快速路出口
	};

	struct Spot
	{
		SpotType spotType; // 场所类型
		Double distance; // [m] Distance between the spot and subject vehicle / 本车到场所的距离
	};

	enum class TrafficStatus
	{
		Unknown = 0, // 未知
		Open = 1, // 畅通
		Slow = 2, // 缓慢
		Crowded = 3, // 拥挤
		Reverse = 4, // Only for adjacent lane traffic / 逆向（仅限相邻车道交通状况）
	};

	enum class WindDirection
	{
		Unknown = 0, // 未知
		East = 1, // 东风
		South = 2, // 南风
		West = 3, // 西风
		North = 4, // 北风
		SouthEast = 5, // 东南风
		NorthEast = 6, // 东北风
		SouthWest = 7, // 西南风
		NorthWest = 8, // 西北风
	};

	enum class RoadSurfaceStatus
	{
		Unknown = 0, // 未知
		Dry = 1, // 干燥
		Wet = 2, // 湿滑
		SnowCovered = 3, // 积雪
		Frozen = 4, // 结冰
	};

	enum class DisasterStatus
	{
		Unknown = 0, // 未知
		No = 1, // 无灾害
		Yes = 2, // 有灾害
	};

	struct EnvSampleData
	{
		WeatherType weatherType; // 天气类型
		OptionalDouble temperature; // [°C] 温度
		OptionalDouble humidity; // [%] Relative humidity / 相对湿度
		OptionalDouble pressure; // [mb] Atmospheric pressure / 气压
		OptionalDouble pm25; // [ug/m3] PM 2.5
		OptionalDouble pm10; // [ug/m3] PM 10
		OptionalDouble o3Concentration; // [ppb] Ozone concentration / 臭氧浓度
		OptionalDouble coConcentration; // [ppb] Carbon monoxide concentration / 一氧化碳浓度
		OptionalDouble so2Concentration; // [ppb] Sulfur dioxide concentration / 二氧化硫浓度
		OptionalDouble no2Concentration; // [ppb] Nitrogen dioxide concentration / 二氧化氮浓度
		OptionalDouble visibility; // [KM] 能见度
		OptionalDouble illumination; // [lux] 光照强度
		OptionalDouble totalRadiationIntensity; // [W/m2] 总辐射强度
		OptionalDouble ultravioletRadiationIntensity; // [W/m2] 紫外线辐射强度
		OptionalDouble rainfall; // [mm/min] Instantaneous rainfall / 瞬时雨量
		OptionalDouble cumulativeRainfall; // [mm] 累计雨量
		OptionalDouble windSpeed; // [m/s] 风速
		OptionalDouble accurateWindDirection; // [deg] Accurate wind direction (from), 0 is north wind, CCW is positive, ranges -180~180 / 北风为0，CCW为正，范围在-180～180度
		WindDirection windDirection; // Coarse wind direction (from) / 大致风向
		DisasterStatus typhoonStatus; // 台风状况
		DisasterStatus tornadoStatus; // 龙卷风状况
		DisasterStatus lightningStatus; // 雷电状况
		DisasterStatus hailStatus; // 冰雹状况

		String roadName; // 道路名称
		OptionalInt speedLimit; // [KPH] 道路限速
		RoadType roadType; // 道路类型
		RoadSurfaceStatus roadSurfaceStatus; // 路面状况
		TrafficStatus roadTraffic; // 道路交通状况
		TrafficStatus currentLaneTraffic; // 本车道交通状况
		TrafficStatus leftLaneTraffic; // 左车道交通状况
		TrafficStatus rightLaneTraffic; // 右车道交通状况
		Array<Spot> spots; // 场所列表

		EnvSampleData()
		{
			weatherType = WeatherType::Unknown;
			windDirection = WindDirection::Unknown;
			typhoonStatus = DisasterStatus::Unknown;
			tornadoStatus = DisasterStatus::Unknown;
			lightningStatus = DisasterStatus::Unknown;
			hailStatus = DisasterStatus::Unknown;
			roadType = RoadType::Unknown;
			roadSurfaceStatus = RoadSurfaceStatus::Unknown;
			roadTraffic = TrafficStatus::Unknown;
			currentLaneTraffic = TrafficStatus::Unknown;
			leftLaneTraffic = TrafficStatus::Unknown;
			rightLaneTraffic = TrafficStatus::Unknown;
		}
	};

	class EnvSample : public Object<class EnvSampleVars>
	{
	public:
		SPADAS_TYPE("env_sample_v3.EnvSample")

		EnvSample();
		FullTimestamp& timestamp();
		EnvSampleData *operator ->();

		static String getProtocolName();
		SessionGeneralSample toGeneralSample();

		static Array<String> getProtocolNames();
		Bool fromGeneralSample(String protocol, SessionGeneralSample generalSample);
	};
}

#endif
